#include "cboundingbox.h"

CBoundingBox::CBoundingBox(void *pObject, CPoint3f MinCoord, CPoint3f MaxCoord)
{
    this->m_pBoundedObject = pObject;
    this->m_MinCorner = MinCoord;
    this->m_MaxCorner = MaxCoord;
}

CBoundingBox::~CBoundingBox()
{
}

bool CBoundingBox::intersect(CRay *pRay)
{
    double tmin, tmax, tymin, tymax, tzmin, tzmax;
    if (pRay->m_InvDirection.m_fX >= 0)
    {
        tmin = (this->m_MinCorner.GetX() - pRay->m_Start.GetX()) * pRay->m_InvDirection.m_fX;
        tmax = (this->m_MaxCorner.GetX() - pRay->m_Start.GetX()) * pRay->m_InvDirection.m_fX;
    }
    else
    {
        tmin = (this->m_MaxCorner.GetX() - pRay->m_Start.GetX()) * pRay->m_InvDirection.m_fX;
        tmax = (this->m_MinCorner.GetX() - pRay->m_Start.GetX()) * pRay->m_InvDirection.m_fX;
    }
    if (pRay->m_InvDirection.m_fY >= 0)
    {
        tymin = (this->m_MinCorner.GetY() - pRay->m_Start.GetY()) * pRay->m_InvDirection.m_fY;
        tymax = (this->m_MaxCorner.GetY() - pRay->m_Start.GetY()) * pRay->m_InvDirection.m_fY;
    }
    else
    {
        tymin = (this->m_MaxCorner.GetY() - pRay->m_Start.GetY()) * pRay->m_InvDirection.m_fY;
        tymax = (this->m_MinCorner.GetY() - pRay->m_Start.GetY()) * pRay->m_InvDirection.m_fY;
    }

    if ( (tmin > tymax) || (tymin > tmax) )
        return false;
    if (tymin > tmin)
        tmin = tymin;
    if (tymax < tmax)
        tmax = tymax;

    if (pRay->m_InvDirection.m_fZ >= 0)
    {
        tzmin = (this->m_MinCorner.GetZ() - pRay->m_Start.GetZ()) * pRay->m_InvDirection.m_fZ;
        tzmax = (this->m_MaxCorner.GetZ() - pRay->m_Start.GetZ()) * pRay->m_InvDirection.m_fZ;
    }
    else
    {
        tzmin = (this->m_MaxCorner.GetZ() - pRay->m_Start.GetZ()) * pRay->m_InvDirection.m_fZ;
        tzmax = (this->m_MinCorner.GetZ() - pRay->m_Start.GetZ()) * pRay->m_InvDirection.m_fZ;
    }

    if ( (tmin > tzmax) || (tzmin > tmax) )
        return false;
    if (tzmin > tmin)
        tmin = tzmin;
    if (tzmax < tmax)
        tmax = tzmax;
    return ( (tmin < pRay->m_fTmax) && (tmax > pRay->m_fTmin) );
}

std::string CBoundingBox::className()
{
    return std::string("CBoundingBox");
}

void CBoundingBox::getBoundingBox(CPoint3f &Pmin, CPoint3f &Pmax)
{
    Pmin = this->m_MinCorner;
    Pmax = this->m_MaxCorner;
}
